<template>
    <div :style="{width: `${width}px`,height: `${height}px`}">
        <el-scrollbar ref="scrollbarRef">
            <div class="logic-tree-container" ref="logicTreeContainerRef">
                <!-- <LogicTree /> -->
                <div style="padding:20px 120px 20px 20px;">
                    <LogicTree :nodes="nodes" @click="handClick" />
                    <svg class="lines-container" :width="actualWidth" :height="actualHeight">
                        <path v-for="(connection, index) in allConnections" :key="index"
                            :d="getCurvePath(connection.parentRightCenter, connection.childLeftCenter)"
                            stroke="var(--el-color-primary)" stroke-width="1.5" fill="transparent" />
                    </svg>
                </div>
            </div>
            <!-- <div class="expand-btn">
                <svg-icon v-if="!isExpand" name="expand" width="20px" height="20px" @click="changeWindow" color="var(--el-text-color-regular)" />    
                <svg-icon v-if="isExpand" name="collapse" width="20px" height="20px" @click="changeWindow" color="var(--el-text-color-regular)" />            
            </div> -->
        </el-scrollbar>
    </div>
</template>

<script setup lang="ts">
import LogicTree from './logicTreeDemo.vue';
import { ElScrollbar } from 'element-plus';
const props = defineProps<{
    nodes: NodeDemo[]; 
    width: number;
    height: number;
}>();
// const clinetWidth = ref(`${props.width}px`);
// const clinetHeight = ref(`${props.height}px`);
// 创建一个响应式的对象，包含宽度和高度
// const isExpand = ref(false);
// const changeWindow = () => {    
//     if (isExpand.value) {
//         clinetWidth.value = `${props.width}px`;
//         clinetHeight.value = `${props.height}px`;
//     } else {
//         clinetWidth.value = '100%';
//         clinetHeight.value = '100%';
//     }
//     isExpand.value = !isExpand.value;
// }
// console.log('styleObject',styleObject)
// 定义 Node 类型
export interface NodeDemo {
    id: number;     //节点的唯一键
    grade: number,  //节点层级
    type: string;   // 节点类型 data、or、and 
    data: { name: string };    //节点的内容
    nodeRef?: HTMLElement;
    centerPoint?: {
        leftCenter: { x: number; y: number }
        rightCenter: { x: number; y: number }
    };
    children?: NodeDemo[];  //子节点
}
// 计算最大 ID
function calculateMaxId(nodes: NodeDemo[]): number {
    return nodes.reduce((max, node) => {
        const nodeId = node.id;
        const childMaxId = node.children ? calculateMaxId(node.children) : 0;
        return Math.max(max, nodeId, childMaxId);
    }, 0);
}
// 初始化节点数据
const maxId = ref<number>(0);
const logicTreeContainerRef = ref<HTMLElement | null>(null);
provide('maxId', maxId)
//处理节点之间的连线，等所有节点都渲染完成之后画线
//滚动条
const scrollX = ref(0);
const scrollY = ref(0);
// 响应式变量存储实际的宽和高
const actualWidth = ref(0);
const actualHeight = ref(0);
const scrollbarRef = ref<InstanceType<typeof ElScrollbar>>()
// 获取 scrollTop 的方法
const getScrollTop = async () => {
    // await nextTick(); // 确保组件已经渲染
    const scrollbar = scrollbarRef.value;
    if (scrollbar && scrollbar.wrapRef) {
        scrollX.value = scrollbar.wrapRef.scrollLeft;
        scrollY.value = scrollbar.wrapRef.scrollTop; // Element Plus 内部使用 wrap 元素作为滚动容器
        const content = scrollbar.wrapRef.querySelector('.logic-tree');
        if (content) {
            actualWidth.value = content.clientWidth + 20;  //加上logic-tree-container的padding
            actualHeight.value = content.clientHeight + 30; //加上logic-tree-container的padding                     
        }
    }
};

//1、寻找node节点的左右中心点
interface Point {
    x: number;
    y: number;
}
const logicTreeContainerLeft = ref<number>(0);
const logicTreeContainerTop = ref<number>(0);
const getLogicTreeContainerRect = async () => {
    if (logicTreeContainerRef.value) {
        const rect = logicTreeContainerRef.value.getBoundingClientRect();
        logicTreeContainerLeft.value = rect.left;
        logicTreeContainerTop.value = rect.top;
    }
}
const getNodeCenterPoints = (nodeRef: HTMLElement): Promise<{ leftCenter: Point; rightCenter: Point }> => {
    return new Promise((resolve) => {
        const rect = nodeRef.getBoundingClientRect();
        const leftCenterX = rect.left - logicTreeContainerLeft.value + scrollX.value; // 假设左边中心为宽度的25%
        const rightCenterX = rect.left + rect.width - logicTreeContainerLeft.value + scrollX.value; // 假设右边中心为宽度的75%
        const centerY = rect.top + rect.height / 2 - logicTreeContainerTop.value + scrollY.value;
        resolve({
            leftCenter: { x: leftCenterX, y: centerY },
            rightCenter: { x: rightCenterX, y: centerY },
        });
    });
};
const setNodeCenterPoints = async (nodes: NodeDemo[]) => {
    const promises = nodes.map(async (node) => {
        if (node.nodeRef) {
            // await nextTick();
            const points = await getNodeCenterPoints(node.nodeRef);
            node.centerPoint = points;
        }
        if (node.children) {
            // 等待子节点的中心点设置完成
            await setNodeCenterPoints(node.children);
        }
    });
    // 等待所有节点的中心点设置完成
    await Promise.all(promises);
};
//
interface Connection {
    parentId: number;
    childId: number;
    parentRightCenter: Point;
    childLeftCenter: Point;
}
const allConnections: Ref<Connection[]> = ref([]);
const collectConnections = (node: NodeDemo, connections: Connection[]): void => {
    if (node.centerPoint && node.children) {
        node.children.forEach((child) => {
            if (child.centerPoint && node.centerPoint) {
                connections.push({
                    parentId: node.id,
                    childId: child.id,
                    parentRightCenter: node.centerPoint.rightCenter,
                    childLeftCenter: child.centerPoint.leftCenter
                });
            }
            collectConnections(child, connections);
        });
    }
};
const updateNodeLine = async () => {
    await nextTick();
    await getScrollTop();
    await setNodeCenterPoints(props.nodes);
    allConnections.value.length = 0;
    collectConnections(props.nodes[0], allConnections.value);
    // console.log('是否执行updateNodeLine',props.nodes,allConnections.value)
}

provide('updateNodeLine', updateNodeLine)
const handClick = () => {
    updateNodeLine();
}
//画线
const getCurvePath = (start: any, end: any) => {
    // 控制点取中间点
    const circleRadius = end.y > start.y ? 8 : (end.y === start.y ? 0 : -8);
    const circleDirection = end.y >= start.y ? 1 : 0;
    const midX = (start.x + end.x) / 2;
    // 横线到中间点
    let path = `M ${start.x} ${start.y} L ${midX - Math.abs(circleRadius)} ${start.y}`;

    // 向右的小圆弧
    path += ` A 8 8 0 0 ${circleDirection} ${midX} ${start.y + circleRadius}`;

    // 竖线到终点
    path += ` V ${end.y - circleRadius}`;

    // 向右的小圆弧
    path += ` A 8 8 0 0 ${1 - circleDirection} ${midX + Math.abs(circleRadius)} ${end.y}`;

    // 横线到终点
    path += ` L ${end.x} ${end.y}`;

    return path;
}
onMounted(async () => {
    // 初始化 maxId
    maxId.value = calculateMaxId(props.nodes);
    await getLogicTreeContainerRect(); // 在组件挂载后调用异步函数
    updateNodeLine();
})

</script>

<style scoped lang="scss">
.logic-tree-container {
    display: flex;
    position: relative;
    // padding: 50px 20px 30px 30px;   
}

.lines-container {
    position: absolute;
    top: 0px;
    left: 0px;
    pointer-events: none;
}
.expand-btn{
    top: 10px;
    left: 10px;
    position: absolute;
    cursor: pointer;
}
</style>
